#include "DXShader.h"
#include "DXMesh.h"
#include "DXEngine.h"

#include <dxerr.h>



 CDXShader::~CDXShader()
 {
	 ReleaseCOM(m_pEffect);
 }


void CDXShader::load(const char *szFileName)
{
#if defined(DEBUG) | defined(_DEBUG)
	DWORD fwShaderFlags = D3DXFX_NOT_CLONEABLE | D3DXSHADER_DEBUG | D3DXSHADER_NO_PRESHADER;
	
#else
	DWORD fwShaderFlags = D3DXSHADER_NO_PRESHADER;
#endif
	assert(CDXEngine::getInstance()->getD3DDevice() != NULL);
	assert(szFileName != NULL);

	LPD3DXBUFFER errors =NULL;
	
	HR(D3DXCreateEffectFromFile(CDXEngine::getInstance()->getD3DDevice(), szFileName, NULL, NULL, fwShaderFlags, NULL, &m_pEffect, &errors));
#if defined(DEBUG) | defined(_DEBUG)
	if (errors)
	{
		DXTrace(__FILE__, __LINE__, S_FALSE, (char *)errors->GetBufferPointer(), FALSE);
	}
#endif
	assert(errors == NULL);
}


void CDXShader::update()
{
	typMapParm::iterator ite;
	
	for (ite = m_mapParms.begin(); ite != m_mapParms.end(); ++ite)
	{
		D3DXHANDLE hVar = NULL;
		
		hVar = m_pEffect->GetParameterByName(0, (*ite).first.c_str());
		switch ((*ite).second.first)
		{
		case CShader::Float:
			{
				HR(m_pEffect->SetValue(hVar, (*ite).second.second, sizeof(float)));
			}
			break;
		case CShader::Vector3:
			{
				HR(m_pEffect->SetValue(hVar, (*ite).second.second, sizeof(D3DXVECTOR3)));
			}
			break;
		case CShader::Vector4:
			{
				HR(m_pEffect->SetValue(hVar, (*ite).second.second, sizeof(D3DXVECTOR4)));
			}
			break;
		case CShader::Matrix:
			{
				HR(m_pEffect->SetMatrix(hVar,  static_cast<const D3DXMATRIX *>((*ite).second.second)));
			}
			break;
		default:
			break;
		}
	}
}

void CDXShader::render(MeshPtr mesh)
{
	unsigned int uiPasses = 0;
	
	HR(m_pEffect->Begin(&uiPasses, 0));
	for (unsigned int i = 0; i < uiPasses; ++i)
	{
		HR(m_pEffect->BeginPass(i));
		mesh->render();
		HR(m_pEffect->EndPass());
	}
	HR(m_pEffect->End());
}

